package com.example.jwtauthdemo.service.impl;

import com.example.jwtauthdemo.model.User;
import com.example.jwtauthdemo.mapper.UserMapper;
import com.example.jwtauthdemo.service.AuthService;
import com.example.jwtauthdemo.util.JwtUtil;
import com.example.jwtauthdemo.dto.LoginRequest;
import com.example.jwtauthdemo.dto.RegisterRequest;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
public class AuthServiceImpl implements AuthService {

    private final AuthenticationManager authenticationManager;
    private final UserMapper userMapper;
    private final PasswordEncoder passwordEncoder;
    private final JwtUtil jwtUtil;

    public AuthServiceImpl(AuthenticationManager authenticationManager, UserMapper userMapper, PasswordEncoder passwordEncoder, JwtUtil jwtUtil) {
        this.authenticationManager = authenticationManager;
        this.userMapper = userMapper;
        this.passwordEncoder = passwordEncoder;
        this.jwtUtil = jwtUtil;
    }

    // 用户注册
    @Override
    public User register(RegisterRequest registerRequest) {
        String username = registerRequest.getUsername();
        String password = registerRequest.getPassword();
        Integer role = registerRequest.getRole();
        // 检查用户名是否已存在
        if (userMapper.existsByUsername(username)) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 创建新用户
        User user = new User();
        user.setUsername(username);
        user.setPassword(passwordEncoder.encode(password));
        user.setRole(role);
        
        userMapper.save(user);
        return userMapper.findByUsername(username).orElseThrow(() -> new RuntimeException("用户创建失败"));
    }

    // 用户登录
    @Override
    public String login(LoginRequest loginRequest) {
        String username = loginRequest.getUsername();
        String password = loginRequest.getPassword();
        System.out.println("尝试登录: 用户名=" + username + ", 密码=" + password);
        
        // 打印密码编码器类型
        System.out.println("密码编码器类型: " + passwordEncoder.getClass().getName());
        
        // 测试加密当前输入的密码
        String encodedTestPassword = passwordEncoder.encode(password);
        System.out.println("当前输入密码加密后: " + encodedTestPassword);
        
        // 先查询用户信息查看数据库中的密码
        User dbUser = userMapper.findByUsername(username).orElse(null);
        if (dbUser != null) {
            System.out.println("数据库中查到用户: " + dbUser.getUsername());
            System.out.println("数据库中的密码: " + dbUser.getPassword());
            
            // 尝试用当前的passwordEncoder直接验证
            boolean passwordMatch = passwordEncoder.matches(password, dbUser.getPassword());
            System.out.println("密码匹配结果: " + passwordMatch);
            
            // 验证数据库中的密码是否以 $2a$ 开头（BCrypt的标识）
            System.out.println("数据库密码是否为BCrypt格式: " + 
                (dbUser.getPassword() != null && dbUser.getPassword().startsWith("$2a$")));
        } else {
            System.out.println("数据库中未查到用户: " + username);
        }
        
        try {
            // 认证用户
            System.out.println("开始Spring Security认证...");
            Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(username, password)
            );
            
            System.out.println("认证成功，设置安全上下文");
            SecurityContextHolder.getContext().setAuthentication(authentication);
            
            // 生成JWT令牌
            User user = userMapper.findByUsername(username).orElseThrow(() -> new RuntimeException("用户不存在"));
            System.out.println("生成JWT令牌，用户ID: " + user.getId());
            return jwtUtil.generateToken(username, user.getId().toString());
        } catch (Exception e) {
            System.out.println("认证失败: " + e.getMessage());
            e.printStackTrace();
            throw e;
        }

    }
    
    @Override
    public User getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        return userMapper.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
    }
}
    